package com.ux.control
{
	import com.greensock.TweenMax;
	import com.ux.util.MovieClipUtil;
	
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.media.SoundLoaderContext;
	import flash.media.SoundTransform;
	import flash.net.URLRequest;
	
	
	/**
	 * @author winnie
	 */	
	public class SoundPlayer extends Sprite
	{
		public static const PLAY : String = "soundPlayer_play"
		public static const STOP : String = "soundPlayer_stop"
		public static const PAUSE : String = "soundPlayer_pause"
		
		public var channel:SoundChannel;
		private var _status : String;
		private var _skinPause : MovieClip;
		private var _skinStop : MovieClip;
		
		private var sound : Sound;
		private var trans:SoundTransform;
		private var pausePosition : int			= 0;
		
		// 볼륨 컨트롤
		public var volumeNum : Number			= 0;
		private var userControlVolum : Number 	= 100;
		
		public function SoundPlayer( _url : String = "", soundClass : Class = null )
		{
			super();
			
			trans = new SoundTransform( volumeNum, 0 );
			_status = STOP;
			
			if( _url != "" )
			{
				sound = new Sound();
				var _context : SoundLoaderContext	= new SoundLoaderContext( 500, true );
				this.sound.load( new URLRequest( _url ), _context );
			}
			
			if( soundClass != null )
			{
				sound = new soundClass();
			}
		}
		
		
		
		//--------- 사운드 재생 -----------------//
		public function playSound():void
		{
			// trace( "sound play" );
			_status = PLAY;
			skinControl();
			
			if( this.channel )
			{
				// trace("아직 재생중인데 Play버튼을 눌렀을 때");
				this.removeEventListener( Event.ENTER_FRAME, onVolumeDownEnter );
				this.addEventListener( Event.ENTER_FRAME, onVolumeUpEnter );
			}
			else
			{
				// trace("완전 꺼졌는데 Play버튼을 눌렀을 때");
				this.trans.volume				= 0;
				this.channel					= this.sound.play(pausePosition);
				this.channel.soundTransform		= this.trans;
				
				this.channel.addEventListener(Event.SOUND_COMPLETE, onSoundCompleteHandler);
				this.addEventListener( Event.ENTER_FRAME, onVolumeUpEnter );
			}
		}
		
		
		//--------- 사운드 멈춤 -----------------//
		public function stopSound():void
		{
//			 trace( "sound stop" );
			_status = STOP;
			skinControl();
			
			if( channel == null ) return;
			this.pausePosition	= 0;
			this.channel.removeEventListener(Event.SOUND_COMPLETE, onSoundCompleteHandler);
			this.removeEventListener( Event.ENTER_FRAME, onVolumeUpEnter );
			this.addEventListener( Event.ENTER_FRAME, onVolumeDownEnter );
		}
		
		
		//--------- 사운드 일시정지 -----------------//
		public function pauseSound():void
		{
//			 trace( "sound pause" );
			_status = PAUSE;
			skinControl();
			
			this.pausePosition	= this.channel.position;
			this.channel.removeEventListener(Event.SOUND_COMPLETE, onSoundCompleteHandler);
			this.removeEventListener( Event.ENTER_FRAME, onVolumeUpEnter );
			this.addEventListener( Event.ENTER_FRAME, onVolumeDownEnter );
		}
		
		private function onVolumeUpEnter( e:Event ):void
		{
			if( this.volumeNum < userControlVolum )
			{
				this.trans.volume				= this.volumeNum/100;
				this.channel.soundTransform		= this.trans;
				
				this.volumeNum++;
				this.volumeNum++;
				this.volumeNum++;
			}
			else
			{
				this.removeEventListener( Event.ENTER_FRAME, onVolumeUpEnter );
			}
		}
		
		private function onVolumeDownEnter( e:Event ):void
		{
			if( this.channel == null ) return;
			
			if( this.channel != null )
			{
				if( this.volumeNum > 0 )
				{
					this.trans.volume				= this.volumeNum/100;
					this.channel.soundTransform		= this.trans;
					
					this.volumeNum--;
					this.volumeNum--;
					this.volumeNum--;
				}
				else
				{
					this.channel.stop();
					this.channel					= null;
					this.removeEventListener( Event.ENTER_FRAME, onVolumeDownEnter );
				}
			}
			else
			{
				this.removeEventListener( Event.ENTER_FRAME, onVolumeDownEnter );
			}
		}
		
		
		private function onSoundCompleteHandler( e:Event ):void
		{
			this.channel					= this.sound.play();
			this.trans.volume				= this.userControlVolum/100;
			this.channel.soundTransform		= this.trans;
			this.channel.addEventListener( Event.SOUND_COMPLETE, onSoundCompleteHandler );
		}
		
		
		
		
		private function onPause( e:MouseEvent ):void
		{
			if( _status == PLAY )
			{
				pauseSound();
			}
			else
			{
				playSound();
			}
		}
		
		private function onStop( e:MouseEvent ):void
		{
			if( _status == PLAY )
			{
				stopSound();
			}
			else
			{
				playSound();
			}
		}
		
		
		private function skinControl():void
		{
			if( status == PLAY )
			{
				if( _skinPause ) MovieClipUtil.moveFrame( _skinPause, 1 );
				if( _skinStop ) MovieClipUtil.moveFrame( _skinStop, 1 );
			}
			else
			{
				if( _skinPause ) MovieClipUtil.moveFrame( _skinPause, _skinPause.totalFrames );
				if( _skinStop ) MovieClipUtil.moveFrame( _skinStop, _skinStop.totalFrames );
			}
		}
		
		
		//-----------------------------------------------------------------------------------
		//
		// api
		//
		//-----------------------------------------------------------------------------------
		
		
		/** 0~1 **/
		public function set volume( _vol:Number ):void
		{
			this.userControlVolum 					= _vol*100;
			
			TweenMax.to( this, 1, {volumeNum:userControlVolum, onUpdate:volumeChange} );
		}
		
		private function volumeChange():void
		{
			this.trans.volume = this.volumeNum/100;
			if( channel ) this.channel.soundTransform = this.trans;
		}
		
		/** 0~1 **/
		public function get volume():Number
		{
			return this.volumeNum/100;
		}
		
		public function get status():String
		{
			return _status;
		}
		
		
		public function set skinToPause( _skin:MovieClip ):void
		{
			_skinPause = _skin;
			if( !_skinPause.hasEventListener( MouseEvent.CLICK ) )
			{
				_skinPause.addEventListener(MouseEvent.CLICK, onPause );
			}
		}
		
		public function set skinToStop( _skin:MovieClip ):void
		{
			_skinStop = _skin;
			if( !_skinStop.hasEventListener( MouseEvent.CLICK ) )
			{
				_skinStop.addEventListener(MouseEvent.CLICK, onStop );
			}
		}
	}
}








